#include "stdafx.h"
#include "XThemeImpl.h"

#include "IXStringBundleMgr.h"

#include <algorithm>

#include "IXWindow.h"
#include "IntSkinImpl.h"
#include "Colorize.h"

IMPLEMENT_SKIN_CLASS(CXThemeImpl);


//////////////////////////////////////////////////////////////////////////

IXThemeListener::IXThemeListener()
{
    XInstPtr<IXTheme> pTheme;
    XASSERT_ERROR(pTheme != NULL, _T("Failed to create IXTheme*"));
    if(pTheme != NULL)
        pTheme->AddThemeListener(dynamic_cast<IXThemeListener*>(this));
}

IXThemeListener::~IXThemeListener()
{
    if(Util::GetSkinCoreStatus() == Util::CoreStatus_Ready)
    {
        XInstPtr<IXTheme> pTheme;
        XASSERT_ERROR(pTheme != NULL, _T("Failed to create IXTheme*"));
        if(pTheme != NULL)
        {
            pTheme->RemoveThemeListener(this);
        }
    }
}

//////////////////////////////////////////////////////////////////////////

CXThemeImpl::CXThemeImpl()
{
    m_nColorHue = 0;
    m_nColorSat = 0;
    m_nColorLight = 0;
}

CXThemeImpl::~CXThemeImpl()
{
    ;
}

//////////////////////////////////////////////////////////////////////////
// IXTheme

HRESULT CXThemeImpl::put_Lang(IN LPCTSTR szLang)
{
    XInstPtr<IXStringBundleMgr> pSBM;
    if(pSBM == NULL)
        return E_FAIL;

    HRESULT hResult = pSBM->put_Lang(szLang);
    if(hResult == S_OK)
        hResult = InvokeThemeListener(eSS_Lang, NULL);

    return hResult;
}

HRESULT CXThemeImpl::get_Lang(OUT BSTR* pbstrLang)
{
    XInstPtr<IXStringBundleMgr> pSBM;
    if(pSBM == NULL)
        return E_FAIL;

    HRESULT hResult = pSBM->get_Lang(pbstrLang);
    return hResult;
}

HRESULT CXThemeImpl::put_HSL(IN int nHue, IN int nSat, IN int nLight)
{
    if(nHue == m_nColorHue
        && nSat == m_nColorSat
        && nLight == m_nColorLight)
    {
        return S_OK;
    }


    XASSERT_ERROR(nHue <= 180 && nHue >= -180, _T("Invalid HSL"));
    XASSERT_ERROR(nSat <= 100 && nSat >= -100, _T("Invalid HSL"));
    XASSERT_ERROR(nLight <= 20 && nLight >= -20, _T("Invalid HSL"));

    if(nHue < -180 && nHue > 180
        || nSat < -100 && nSat > 100
        || nLight < -20 && nLight > 20)
    {
        return E_FAIL;
    }

    m_nColorHue = nHue;
    m_nColorSat = nSat;
    m_nColorLight = nLight;

    HRESULT hResult = InvokeThemeListener(eSS_HSL, NULL);
    return hResult;
}

HRESULT CXThemeImpl::get_HSL(OUT int* pnHue, OUT int* pnSat, OUT int* pnLight)
{
    *pnHue = m_nColorHue;
    *pnSat = m_nColorSat;
    *pnLight = m_nColorLight;
    return S_OK;
}

HRESULT CXThemeImpl::AddThemeListener(IXThemeListener* pListener)
{
#ifdef _DEBUG
    XASSERT_ERROR(std::find(m_ThemeListener.begin(), m_ThemeListener.end(), pListener) == m_ThemeListener.end(), _T("ThemeListener Add Twice!"));
#endif // _DEBUG
    m_ThemeListener.push_back(pListener);
    return S_OK;
}

HRESULT CXThemeImpl::RemoveThemeListener(IXThemeListener* pListener)
{
    ThemeListenerList::iterator Ite = std::find(m_ThemeListener.begin(), m_ThemeListener.end(), pListener);
    XASSERT_ERROR(Ite != m_ThemeListener.end(), _T("ThemeListener Not Registered!"));
    if(Ite != m_ThemeListener.end())
        m_ThemeListener.erase(Ite);
    return S_OK;
}

COLORREF CXThemeImpl::AdjustColor(COLORREF Color)
{
    return Colorize::AdjustColorPixel(Color, m_nColorHue, m_nColorSat, m_nColorLight);
}

HRESULT CXThemeImpl::InvokeThemeListener(eSkinSettingFlag flag, LPARAM lParam)
{
    HRESULT hResult = S_OK;
    HRESULT hResultTemp = S_OK;
    ThemeListenerList::iterator Ite = m_ThemeListener.begin();
    for(; Ite != m_ThemeListener.end(); ++ Ite)
    {
        IXThemeListener*& pListener = *Ite;
        hResultTemp = pListener->OnThemeChanged(flag, lParam);
        if(hResultTemp != hResult)
            hResult = hResultTemp;
    }
    return hResult;
}
